﻿using System;
using System.Configuration;
using System.Net;
using System.ServiceModel;
using Contracts.ServiceContracts.Reporting;
using Types.CustomTypes;
using Types.Enumerations;

namespace Services.BusinessObjects.Reporting
{
	[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
	internal class ReportingBS : IReporting
	{
		private static string mReportServiceURL;
		private static string mReportExecutionURL;
		private static string mRaporUser;
		private static string mRaporPassword;
		private static string mRaporCredentialsDomain;
		private static NetworkCredential mCredential;


		static ReportingBS()
		{
			mReportServiceURL = ConfigurationManager.AppSettings["ReportServiceURL"].ToString();
			mReportExecutionURL = ConfigurationManager.AppSettings["ReportExecutionURL"].ToString();

			mRaporUser = ConfigurationManager.AppSettings["RaporUser"].ToString();
			mRaporPassword = ConfigurationManager.AppSettings["RaporPassword"].ToString();
			mRaporCredentialsDomain = ConfigurationManager.AppSettings["RaporCredentialsDomain"].ToString();
			mCredential = new NetworkCredential(mRaporUser, mRaporPassword, mRaporCredentialsDomain);

			//mCredential = CredentialCache.DefaultNetworkCredentials;

		}



		#region IRaporlama Members

		public string RenderReport(Types.CustomTypes.ReportHelper pRaporYardimcisi)
		{

			Warning[] warnings;
			string[] streamids;
			string mimeType;
			string encoding;
			string extension;
			ParameterValue[] parameters = null;
			byte[] buf = null;

			parameters = new ParameterValue[pRaporYardimcisi.RaporParametreleri.Count];
			for (int i = 0; i < pRaporYardimcisi.RaporParametreleri.Count; i++)
			{
				parameters[i] = new ParameterValue();

				parameters[i].Name = pRaporYardimcisi.RaporParametreleri[i].mParametreAdi;
				parameters[i].Value = pRaporYardimcisi.RaporParametreleri[i].mParametreDegeri;
			}

			using (ReportExecutionService rs = new ReportExecutionService())
			{
				rs.Url = mReportExecutionURL;
				rs.Credentials = mCredential;
				ExecutionInfo execInfo = new ExecutionInfo();
				ExecutionHeader execHeader = new ExecutionHeader();
				rs.Timeout = 500000;
				rs.ExecutionHeaderValue = execHeader;
				execInfo = rs.LoadReport(pRaporYardimcisi.RaporAdi, null);
				rs.SetExecutionParameters(parameters, "tr-tr");


				buf = rs.Render(pRaporYardimcisi.RaporFormatString, pRaporYardimcisi.DeviceInfo, out extension, out encoding, out mimeType, out warnings, out streamids);
			}

			return Convert.ToBase64String(buf);

		}


		private ParameterValue[] ExtensionParametersForMail(ReportHelper pRaporYardimcisi)
		{
			ParameterValue[] extensionParamsEmail = new ParameterValue[8];
			extensionParamsEmail[0] = new ParameterValue();
			extensionParamsEmail[0].Name = "TO";
			extensionParamsEmail[0].Value = pRaporYardimcisi.SubscriberEMail;
			extensionParamsEmail[2] = new ParameterValue();
			extensionParamsEmail[2].Name = "IncludeReport";
			extensionParamsEmail[2].Value = "True";
			extensionParamsEmail[3] = new ParameterValue();
			extensionParamsEmail[3].Name = "RenderFormat";
			extensionParamsEmail[3].Value = pRaporYardimcisi.RaporFormatString;
			extensionParamsEmail[4] = new ParameterValue();
			extensionParamsEmail[4].Name = "Subject";
			extensionParamsEmail[4].Value = "@ReportName Oluşturulma Zamanı : @ExecutionTime";
			extensionParamsEmail[5] = new ParameterValue();
			extensionParamsEmail[5].Name = "Comment";
			extensionParamsEmail[5].Value = "Dosyanız Ektedir..";
			extensionParamsEmail[6] = new ParameterValue();
			extensionParamsEmail[6].Name = "IncludeLink";
			extensionParamsEmail[6].Value = "False";
			extensionParamsEmail[7] = new ParameterValue();
			extensionParamsEmail[7].Name = "Priority";
			extensionParamsEmail[7].Value = "NORMAL";

			return extensionParamsEmail;
		}

		private ParameterValue[] ExtensionParametersForFileShare(ReportHelper pRaporYardimcisi)
		{

			ParameterValue[] extensionParamsFileShare = new ParameterValue[7];
			extensionParamsFileShare[0] = new ParameterValue();
			extensionParamsFileShare[0].Name = "FILENAME";
			extensionParamsFileShare[0].Value = pRaporYardimcisi.RaporDosyaAd;
			extensionParamsFileShare[1] = new ParameterValue();
			extensionParamsFileShare[1].Name = "FILEEXTN";//File Extension
			extensionParamsFileShare[1].Value = "true";
			extensionParamsFileShare[2] = new ParameterValue();
			extensionParamsFileShare[2].Name = "PATH";
			extensionParamsFileShare[2].Value = ConfigurationManager.AppSettings["ReportServerFileSharePath"].ToString();
			extensionParamsFileShare[3] = new ParameterValue();
			extensionParamsFileShare[3].Name = "RENDER_FORMAT";
			extensionParamsFileShare[3].Value = pRaporYardimcisi.RaporFormatString;
			extensionParamsFileShare[4] = new ParameterValue();
			extensionParamsFileShare[4].Name = "USERNAME";
			extensionParamsFileShare[4].Value = ConfigurationManager.AppSettings["ReportServerFileShareUser"].ToString();
			extensionParamsFileShare[5] = new ParameterValue();
			extensionParamsFileShare[5].Name = "PASSWORD";
			extensionParamsFileShare[5].Value = ConfigurationManager.AppSettings["ReportServerFileSharePassword"].ToString().Decrypt();

			extensionParamsFileShare[6] = new ParameterValue();
			extensionParamsFileShare[6].Name = "WRITEMODE";
			extensionParamsFileShare[6].Value = "Overwrite";

			return extensionParamsFileShare;
		}

		private void Subcsribe(ReportingService2005 rs, ReportHelper pRaporYardimcisi)
		{
			string report = pRaporYardimcisi.RaporAdi;
			string desc = "Kullanıcıya Rapor Gönderme :" + pRaporYardimcisi.SubscriberEMail;
			string eventType = "TimedSubscription";
			string scheduleXml = @"<ScheduleDefinition>";
			int timeMinute = DateTime.Now.Minute + 3;
			int timeHour = DateTime.Now.Hour;
			if (timeMinute > 60)
			{
				timeHour = timeHour + 1;
				if (timeHour > 24)
					timeHour = timeHour - 24;
				timeMinute = timeMinute - 60;
			}
			string saat = timeHour.ToString().Length == 1 ? ("0" + timeHour.ToString()) : timeHour.ToString();
			string dakika = timeMinute.ToString().Length == 1 ? ("0" + timeMinute.ToString()) : timeMinute.ToString();
			DateTime dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
			scheduleXml += @"<StartDateTime>" + dt.Year.ToString() + "-" + dt.Month.ToString() + "-" + dt.Day.ToString() + "T" + saat + ":" + dakika + ":00</StartDateTime></ScheduleDefinition>";

			string matchData = scheduleXml;
			ExtensionSettings extSettings = new ExtensionSettings();

			if (pRaporYardimcisi.DeliveryType == EnumReportDelivery.FileShare)
			{
				extSettings.Extension = "Report Server FileShare";
				extSettings.ParameterValues = ExtensionParametersForFileShare(pRaporYardimcisi);
			}
			else
			{
				extSettings.Extension = "Report Server Email";
				extSettings.ParameterValues = ExtensionParametersForMail(pRaporYardimcisi);
			}

			ParameterValue[] parameters = null;
			parameters = new ParameterValue[pRaporYardimcisi.RaporParametreleri.Count];
			for (int i = 0; i < pRaporYardimcisi.RaporParametreleri.Count; i++)
			{
				parameters[i] = new ParameterValue();
				parameters[i].Name = pRaporYardimcisi.RaporParametreleri[i].mParametreAdi;
				parameters[i].Value = pRaporYardimcisi.RaporParametreleri[i].mParametreDegeri;
			}

			rs.CreateSubscription(pRaporYardimcisi.RaporAdi, extSettings, desc, eventType, matchData, parameters);

		}



		public void CreateSubscription(ReportHelper pRaporYardimcisi)
		{
			using (ReportingService2005 rs = new ReportingService2005())
			{
				rs.Url = mReportServiceURL;
				rs.Credentials = mCredential;

				Subcsribe(rs, pRaporYardimcisi);

			}
		}

		public void CopyReportAndCreateSubscription(ReportHelper pRaporYardimcisi, string pRaporAdinaEklenecekString)
		{

			using (ReportingService2005 rs = new ReportingService2005())
			{
				rs.Url = mReportServiceURL;
				rs.Credentials = mCredential;

				RaporuKopyalaVeDataSourceunuAta(rs, pRaporYardimcisi, pRaporAdinaEklenecekString);
				Subcsribe(rs, pRaporYardimcisi);
			}
		}


		private DataSource GetReportDataSource(string pRaporAdi)
		{
			ReportingService2005 rs = new ReportingService2005();

			rs.Url = mReportServiceURL;
			rs.Credentials = mCredential;

			DataSource[] dSource = rs.GetItemDataSources(pRaporAdi);
			if (dSource.Length <= 0)
				return null;

			return dSource[0];

		}

		private DataSource VarOlanDataSourceReferansiniGetir(string pVarOlanDataSourceAdi, string pVarOlanDataSourceYolu, string pDondurulecekDataSourceAdi)
		{
			DataSourceReference reference = new DataSourceReference();
			reference.Reference = pVarOlanDataSourceYolu.TrimEnd('/') + "/" + pVarOlanDataSourceAdi;
			DataSource ds = new DataSource();
			ds.Item = (DataSourceDefinitionOrReference)reference;
			ds.Name = pDondurulecekDataSourceAdi;
			return ds;
		}

		private void RaporuKopyalaVeDataSourceunuAta(ReportingService2005 rs, ReportHelper pRaporYardimcisi, string pRaporAdinaEklenecekString)
		{
			string[] splitted = pRaporYardimcisi.RaporAdi.Split('/');
			string yeniRaporAd = splitted[splitted.Length - 1] + "_" + pRaporAdinaEklenecekString;
			splitted[splitted.Length - 1] = String.Empty;
			string raporYolu = String.Join("/", splitted).TrimEnd('/');

			if (!RaporVarmi(rs, yeniRaporAd, raporYolu))
			{
				DataSource dsCurrent = this.GetReportDataSource(pRaporYardimcisi.RaporAdi);
				DataSource dsNew = new DataSource();

				//// TODO : Commentliyorum. Normalde bu datasource'un yaratilmis olmasi gerekli.....Daha sonra açılacak
				//dsNew.Name = dsCurrent.Name + "_" + pRaporAdinaEklenecekString;
				//dsNew.Name = dsCurrent.Name ;

				// 2009-09-28 KB 
				dsNew.Name = dsCurrent.Name + pRaporAdinaEklenecekString;
				dsNew.Item = dsCurrent.Item;

				rs.CreateReport(yeniRaporAd, raporYolu, false, rs.GetReportDefinition(pRaporYardimcisi.RaporAdi), null);
				rs.SetItemDataSources(String.Format("{0}/{1}", raporYolu, yeniRaporAd), new DataSource[] { dsNew });
			}
			pRaporYardimcisi.RaporAdi = String.Format("{0}/{1}", raporYolu, yeniRaporAd);
		}

		private bool RaporVarmi(ReportingService2005 rs, string pYeniRaporAd, string pRaporYolu)
		{
			CatalogItem[] items = null;
			SearchCondition condition = new SearchCondition();
			condition.Condition = ConditionEnum.Equals;
			condition.ConditionSpecified = true;
			condition.Name = "Name";
			condition.Value = pYeniRaporAd;

			SearchCondition[] conditions = new SearchCondition[1];
			conditions[0] = condition;

			items = rs.FindItems(pRaporYolu, BooleanOperatorEnum.And, conditions);
			if (items == null || items.Length == 0)
				return false;
			else
				return true;
		}


		#endregion
	}
}
